#coding:utf-8
"""
程序需求：
文本文件中存储所需要文件的路径和这些文件需要复制到的目标目录。
要将这些文件复制到对应的目录中。
先看文件的内容：

童桂梅-赎楼-20170323
/nas/attach/mbmResource/creditcontract/6782/c66a4343-56f3-4ed6-813b-fd84459249cc.jpg
/nas/attach/mbmResource/creditcontract/6782/0376e01f-c2ef-4f6d-9812-752a1284e563.jpg
/nas/attach/mbmResource/creditcontract/6782/63586033-8ff2-49bf-8940-cb7b27fef065.jpg
/nas/attach/mbmResource/creditcontract/6782/ea37cff6-45da-4bc1-8216-9ef02fd08d6c.jpg
/nas/attach/mbmResource/sealcontract/6782/237046/2017032300_38564_237046.pdf
/nas/attach/mbmResource/sealcontract/6782/237050/2017032300_38215_237050.pdf
/nas/attach/mbmResource/sealcontract/6782/237065/2017032300_34547_237065.pdf
....................
佟利-赎楼-20170718
/nas/attach/mbmResource/creditcontract/6782/c66a4343-56f3-4ed6-813b-fd84459249cc.jpg
/nas/attach/mbmResource/creditcontract/6782/0376e01f-c2ef-4f6d-9812-752a1284e563.jpg
/nas/attach/mbmResource/creditcontract/6782/63586033-8ff2-49bf-8940-cb7b27fef065.jpg
/nas/attach/mbmResource/creditcontract/6782/ea37cff6-45da-4bc1-8216-9ef02fd08d6c.jpg
/nas/attach/mbmResource/sealcontract/6782/237046/2017032300_38564_237046.pdf
/nas/attach/mbmResource/sealcontract/6782/237050/2017032300_38215_237050.pdf
/nas/attach/mbmResource/sealcontract/6782/237065/2017032300_34547_237065.pdf
张立宇-本地宝-20170425 
/nas/attach/mbmResource/creditcontract/6782/c66a4343-56f3-4ed6-813b-fd84459249cc.jpg
/nas/attach/mbmResource/creditcontract/6782/0376e01f-c2ef-4f6d-9812-752a1284e563.jpg
/nas/attach/mbmResource/creditcontract/6782/63586033-8ff2-49bf-8940-cb7b27fef065.jpg
/nas/attach/mbmResource/creditcontract/6782/ea37cff6-45da-4bc1-8216-9ef02fd08d6c.jpg
/nas/attach/mbmResource/sealcontract/6782/237046/2017032300_38564_237046.pdf
/nas/attach/mbmResource/sealcontract/6782/237050/2017032300_38215_237050.pdf
/nas/attach/mbmResource/sealcontract/6782/237065/2017032300_34547_237065.pdf
.......
.......
这个文件存储的规律是目录占一行，接着就是这个目录中需要的文件，这个目录的文件完了后，下一行就是接着下一个目录

现要将 
    "童桂梅(赎楼)20170323" 下的文件复制到"/tmp/童桂梅(赎楼)20170323/" 这个目录下
    "张立宇(本地宝)20170425" 下的文件复制"/tmp/张立宇(本地宝)20170425/" 这个目录下
    ...... 依次类推

/nas/attach/mbmResource/sealcontract/6782/237065/2017032300_34547_237065.pdf 这个绝对路径在服务器上是真实存在的
但是有些文件就不存在，原因就是由于程序出错导致文件丢失

"""
#!/data/usr/local/python3/bin/python3
# -*- coding:utf-8 -*-
import os
import shutil
import re

# 打开txt文件，这个文件存储所需文件的路径和目录
def open_file(path):
    fd = open(path)
    filename_list = fd.readlines()
    return filename_list
    fd.close()


# 这个函数实现的功能：统计每个目录下有多少个文件，不存在的文件有多少个，以及不存在的文件有哪些

def count_file(filename,file_not_exists_list,dirname_list,file_total_nums_list,file_not_exists_nums_list):
    
    """
    file_not_exists_list 这个列表存储不存在的文件。不存在的文件是由于历史原因，程序出错造成有些合同文件丢失
    dirname_list 这个列表存储的目录，目录内的总文件数，不存在文件的数量。这个列表存在的意义就是一个报告，同时也可以验证是否少拷文件
    file_total_nums_list 这个列表存储每个目录中文件的总数
    file_not_exists_nums_list 这个列表存储每个目录中丢失文件的总数
    dirname_list :
    [
        '童桂梅(赎楼)20170323', 		95, 	0, 
        '蒋国安(赎楼)20170725', 		120, 	0, 
        '佟利(赎楼)20170718', 		 71, 	 0,
        .........
    ]
    """
    # 这里不定义一个全局变量，后面就会报变量引用之前需要定义这样的错误
    global dirpath

    if filename == "童桂梅-赎楼-20170323":

        dirname_list.append(filename)
        dirpath = "/tmp/" + filename
        mkdir(dirpath)
        
        
    elif filename[0:4] != "/nas":

        dirname_list.append(sum(file_total_nums_list))
        dirname_list.append(sum(file_not_exists_nums_list))
        dirname_list.append(filename)
        file_total_nums_list = []
        file_not_exists_nums_list = []

        dirpath = "/tmp/" + filename
        mkdir(dirpath)

    elif not os.path.exists(filename):

        file_not_exists_list.append(filename)
        file_not_exists_nums_list.append(1)

    else:

        file_total_nums_list.append(1)

        """
        如果没有定义dirpath这个全局变量，这里就会报dirpath引用之前需要定义这样的错误。
        这里无法理解，文本文件的第一行内容是 "童桂梅-赎楼-20170323" 第1个if 那里dirpath就已经定义了，
        文本文件的第2行才跳到这里,这个时候dirpath已经定义了。
        如果说dirpath作用域的问题，这是同一个函数内，应该在同一个作用域下。
        这里无法理解，只好将dirpath变成全局变量
        """
        newfinename_path = dirpath + filename[filename.rindex("/"):]
        copy_file(filename,newfinename_path)
        
    return(dirname_list,file_not_exists_list,file_total_nums_list,file_not_exists_nums_list)

"""
复制文件，oldname,newname 都是绝对路径。
例如 
    oldname = "/nas/attach/mbmResource/creditcontract/11008/109be30e-1ffe-44e1-aa4a-32e84b6a4f6b.jpg"
    newname = "/tmp/张立宇-本地宝-20170425/109be30e-1ffe-44e1-aa4a-32e84b6a4f6b.jpg"
"""
def copy_file(filename,dirpath):

    shutil.copy(filename,dirpath)


# 创建目录，如果目录存在就先删除，然后在创建
def mkdir(dirpath):

    if not os.path.isdir(dirpath):
        os.mkdir(dirpath)
    else:
        remove_dir(dirpath)
        os.mkdir(dirpath)


# 递归删除目录下的所有文件及子目录
def remove_dir(dirpath):
    if(os.path.isdir(dirpath)):
        for p in os.listdir(dirpath):
            remove_dir(os.path.join(dirpath,p))
        if(os.path.exists(dirpath)):
            os.rmdir(dirpath)
    else:
        if(os.path.exists(dirpath)):
            os.remove(dirpath)


# 将目录名称，目录下的总文件数，以及丢失文件的个数写入文件中，当做报告查看
def write_contact_file_info_to_txt(dirname_list):
    fd1 = open("/tmp/contact.txt","w")
    # 向文件中写表头，由于中文对齐，空格是半角的，和中文汉字的宽度不一致，所以常规方法无法对齐。
    # 使用chr(12288) 这个可以解决对齐的问题，这里也需要自行尝试给多少个空格才能够对齐
    title = "{:<29}".format('目录名称',chr(12288)) + "\t" + "文件总数" + "\t" + "不存在文件的数量"
    fd1.write(title)
    fd1.write("\n")
    for context in dirname_list[::3]:
        写入的内容对齐
        line = "{:<30}".format(context,chr(12288)) + "\t" + str(dirname_list[dirname_list.index(context) + 1]) + "\t" + "\t" + "\t" + str(dirname_list[dirname_list.index(context) + 2])
        fd1.write(line)
        fd1.write("\n")

    fd1.close()

"""
文本文件内容：
目录名称                                文件总数        不存在文件的数量
童桂梅-赎楼-20170323                    95                      0
蒋国安-赎楼-20170725                    120                     0
佟利-赎楼-20170718                      71                      0
张立宇-本地宝-20170425                  175                     0
科图乐-本地宝-20170414                  46                      0
......

这里对齐得并不是很完美
"""

# 将不存在的文件存储在一个文件中，现没有实现那个目录下缺少那些文件，而是将所有缺失的文件(绝对路径)存储到一个文本文件中
def write_contact_file_not_exists_list_to_txt(file_not_exists_list):
    fd = open("/tmp/contact_not_exists_list.txt","w")
    line_context = [line + "\n" for line in file_not_exists_list]
    fd.writelines(line_context)
    fd.close()

def main():
    path = "/tmp/1.txt"
    dirpath = "/tmp/contact"
    filename_list = open_file(path)
    file_not_exists_list = []
    dirname_list = []
    file_total_nums_list = []
    file_not_exists_nums_list = []
    # 设计了这么多list就是为了少循环，一遍循环处理所有的逻辑：统计目录中的文件数量，缺失的文件及其缺失文件的数量，复制文件等
    # 当然可以使用少量的list，将所有的代码写在一个for循环中，这样代码就丧失了模块化
    # 本来想少用list的，可是没有想到好的办法，保存中间变量。很多变量都是通过参数参数传递，这样中间变量总是会丢失
    for filename in filename_list:
        filename = filename.strip()
        dirname_list,file_not_exists_list,file_total_nums_list,file_not_exists_nums_list = count_file(filename,file_not_exists_list,dirname_list,file_total_nums_list,file_not_exists_nums_list)
        
    dirname_list.append(sum(file_total_nums_list))
    dirname_list.append(sum(file_not_exists_nums_list))
    
    write_contact_file_info_to_txt(dirname_list)

    write_contact_file_not_exists_list_to_txt(file_not_exists_list)

    #print("dirname_list: ",dirname_list)
    #print(file_not_exists_list[0:20])


if __name__ == "__main__":
    main()